#include "gnd.h"
#include <string.h>
#include <json-glib/json-glib.h>
#include <stdio.h>

#define MODULE_NAME "GndDeviceInfoModule"

typedef struct _GndDeviceInfoModule
{
    GObject parent;
    GndApp * app;
    GndSession * session;

    gchar * request_data;
    gint request_len;
} GndDeviceInfoModule;


void gnd_device_info_module_interface_init(GndModuleInterface * iface);
void gnd_device_info_module_start(GndDeviceInfoModule * self, gpointer data);
void gnd_device_info_module_stop(GndDeviceInfoModule * self, gpointer data);
void gnd_device_info_module_connect_status(GndDeviceInfoModule * self,
                                           GndSessionStatus status,
                                           gpointer data);

void gnd_device_info_module_connect_cb(GndDeviceInfoModule * self,
                                       GndApp * app);
void gnd_device_info_module_disconnect_cb(GndDeviceInfoModule * self,
                                       GndApp * app);

gboolean gnd_device_info_module_accept_data_cb(GndSessionData * data);

void gnd_device_info_module_ui_set_info_use_json(GndDeviceInfoModule * self,
                                                 JsonObject * object_data);
void gnd_device_info_module_ui_set_info_not_connected(GndDeviceInfoModule * self);


G_DEFINE_TYPE_WITH_CODE(GndDeviceInfoModule,
                        gnd_device_info_module,
                        G_TYPE_OBJECT,
                        G_IMPLEMENT_INTERFACE(GND_TYPE_MODULE,
                                              gnd_device_info_module_interface_init))


GndDeviceInfoModule * gnd_device_info_module_new(GndApp *app)
{
    GndDeviceInfoModule * self = g_object_new(GND_TYPE_DEVICE_INFO_MODULE, NULL);
    self->app = app;
    return self;
}

void gnd_device_info_module_init(GndDeviceInfoModule *self)
{
    self->session = gnd_session_new(GND_MODULE(self));

    //创建请求
    GndMessage * message = gnd_message_new();
    gchar * request_json = "{\"name\":\"gnd_device_info_module\","
                           "\"method\":\"get_device_info\"}";
    gnd_message_add_raw_data(message, request_json, strlen(request_json));
    self->request_len = gnd_message_generate_bin(message, &(self->request_data));
    g_assert(self->request_len);
    gnd_message_free(message);

}

void gnd_device_info_module_class_init(GndDeviceInfoModuleClass *klass)
{

}

void gnd_device_info_module_interface_init(GndModuleInterface * iface)
{
    iface->connect_status =
            (void (*)(GndModule *, int, gpointer)) gnd_device_info_module_connect_status;
    iface->start =
            (void (*)(GndModule *, gpointer)) gnd_device_info_module_start;
    iface->stop =
            (void (*)(GndModule *, gpointer)) gnd_device_info_module_stop;
}

void gnd_device_info_module_start(GndDeviceInfoModule * self, gpointer data)
{
    GndApp * app = self->app;

    gnd_device_info_module_ui_set_info_not_connected(self);

    g_signal_connect_swapped(app, "connect",
                             (GCallback) gnd_device_info_module_connect_cb,
                             (gpointer) self);

    g_signal_connect_swapped(app, "disconnect",
                             (GCallback) gnd_device_info_module_disconnect_cb,
                             (gpointer) self);
}

void gnd_device_info_module_stop(GndDeviceInfoModule * self, gpointer data)
{

}

void gnd_device_info_module_connect_status(GndDeviceInfoModule * self,
                                           GndSessionStatus status,
                                           gpointer data)
{

}

void gnd_device_info_module_connect_cb(GndDeviceInfoModule * self,
                                       GndApp * app)
{

    gnd_connect_add_session(gnd_app_get_connect(app), self->session);
    gnd_session_send_data(self->session,
                          self->request_data,
                          self->request_len);
    gnd_session_accept_data(self->session, 1,
                            (GSourceFunc) gnd_device_info_module_accept_data_cb);

}

void gnd_device_info_module_disconnect_cb(GndDeviceInfoModule * self,
                                       GndApp * app)
{
    gnd_device_info_module_ui_set_info_not_connected(self);
    gnd_session_close(self->session);
}


gboolean gnd_device_info_module_accept_data_cb(GndSessionData *data)
{
    GndDeviceInfoModule * self = GND_DEVICE_INFO_MODULE(data->session->module);

    if (data->status == GND_SESSION_STATUS_FAILURE) {
        g_warning(MODULE_NAME": accept data failure");
        goto end;
    }

    GndMessage * message_rec = gnd_message_new_with_data(data->data,
                                                         data->len);
    if (!message_rec) {
        g_warning(MODULE_NAME": parse message failure");
        //gnd_message_free(message_rec);
        goto end;
    }
    GndMessageData * message_data = g_queue_peek_nth(message_rec->message_data_list,
                                                     0);
    g_assert(message_data);

    JsonParser * json_parser = json_parser_new();
    if (!json_parser_load_from_data(json_parser,
                                    message_data->data,
                                    message_data->len, NULL)) {
        g_warning(MODULE_NAME": parser json failure");
        g_object_unref(json_parser);
        gnd_message_free(message_rec);
        goto end;
    }

    JsonNode * node_root = json_parser_get_root(json_parser);
    g_assert(JSON_NODE_TYPE(node_root) == JSON_NODE_OBJECT);
    JsonObject * object_root = json_node_get_object(node_root);

    gint64 rec_status = json_node_get_int(json_object_get_member(object_root,
                                                                 "status"));
    if ((rec_status & GND_JSON_STATUS_SUCCEED)
            != GND_JSON_STATUS_SUCCEED) {
        g_warning(MODULE_NAME": recive message failure");
        g_object_unref(json_parser);
        gnd_message_free(message_rec);
        goto end;
    }
    //设置界面UI
    gnd_device_info_module_ui_set_info_use_json(self, object_root);
    g_message(MODULE_NAME": set device info");

    g_object_unref(json_parser);
    gnd_message_free(message_rec);
//    JsonNode * root_node =

end:
    return FALSE;
}


void gnd_device_info_module_ui_set_info_use_json(GndDeviceInfoModule *self, JsonObject *object_data)
{
    GndDeviceInfoPage * info_page = gnd_app_get_mainwin(self->app)->device_info_page;
    JsonNode * each_node = NULL;
    gchar * node_data = NULL;
    gchar * str_unknown = "未知";

    //set mainwin device info
    //imei
    node_data = json_object_get_string_member(object_data, "imei");
    if (node_data) {
        gtk_label_set_label(info_page->label_imei_info, node_data);
    } else {
        gtk_label_set_label(info_page->label_imei_info, str_unknown);
    }
    node_data = NULL;
    //mac
    node_data = json_object_get_string_member(object_data, "mac");
    if (node_data) {
        gtk_label_set_label(info_page->label_mac_info, node_data);
    } else {
        gtk_label_set_label(info_page->label_mac_info, str_unknown);
    }
    node_data = NULL;

    //cpu
    node_data = json_object_get_string_member(object_data, "cpu");
    if (node_data) {
        gtk_label_set_label(info_page->label_cpu_info, node_data);
    } else {
        gtk_label_set_label(info_page->label_cpu_info, str_unknown);
    }
    node_data = NULL;


    //android
    node_data = json_object_get_string_member(object_data, "android");
    if (node_data) {
        gtk_label_set_label(info_page->label_sysver_info, node_data);
    } else {
        gtk_label_set_label(info_page->label_sysver_info, str_unknown);
    }
    node_data = NULL;


    //kernel
    node_data = json_object_get_string_member(object_data, "kernel");
    if (node_data) {
        gtk_label_set_label(info_page->label_kernel_info, node_data);
    } else {
        gtk_label_set_label(info_page->label_kernel_info, str_unknown);
    }
    node_data = NULL;

    //sdk_api
    node_data = json_object_get_string_member(object_data, "sdk_api");
    if (node_data) {
        gtk_label_set_label(info_page->label_sdk_api_info, node_data);
    } else {
        gtk_label_set_label(info_page->label_sdk_api_info, str_unknown);
    }
    node_data = NULL;


    //brand
    node_data = json_object_get_string_member(object_data, "brand");
    if (node_data) {
        gtk_label_set_label(info_page->label_brand_info, node_data);
    } else {
        gtk_label_set_label(info_page->label_brand_info, str_unknown);
    }
    node_data = NULL;


    //model
    node_data = json_object_get_string_member(object_data, "model");
    if (node_data) {
        gtk_label_set_label(info_page->label_model_info, node_data);
    } else {
        gtk_label_set_label(info_page->label_model_info, str_unknown);
    }
    node_data = NULL;


    //product
    node_data = json_object_get_string_member(object_data, "product");
    if (node_data) {
        gtk_label_set_label(info_page->label_product_info, node_data);
    } else {
        gtk_label_set_label(info_page->label_product_info, str_unknown);
    }
    node_data = NULL;


    //manufactorer
    node_data = json_object_get_string_member(object_data, "manufacturer");
    if (node_data) {
        gtk_label_set_label(info_page->label_manuf_info, node_data);
    } else {
        gtk_label_set_label(info_page->label_manuf_info, str_unknown);
    }
    node_data = NULL;


    //cpu_abi
    node_data = json_object_get_string_member(object_data, "cpu_abi");
    if (node_data) {
        gtk_label_set_label(info_page->label_cpu_abi_info, node_data);
    } else {
        gtk_label_set_label(info_page->label_cpu_abi_info, str_unknown);
    }
    node_data = NULL;


    //resolution
    gchar * pixel_x = json_object_get_string_member(object_data, "pixel_x");
    gchar * pixel_y = json_object_get_string_member(object_data, "pixel_y");
    if (pixel_x && pixel_y) {
        gchar tmp_buffer[64] = {0};
        g_snprintf(tmp_buffer, 64, "%sx%s", pixel_x, pixel_y);
        gtk_label_set_label(info_page->label_resolution_info,
                            tmp_buffer);
    } else {
        gtk_label_set_label(info_page->label_resolution, str_unknown);
    }

    //ram
    node_data = json_object_get_string_member(object_data, "ram");
    if (node_data) {
        gtk_label_set_label(info_page->label_ram_info, node_data);
    } else {
        gtk_label_set_label(info_page->label_ram_info, str_unknown);
    }
    node_data = NULL;

    //rom
    node_data = json_object_get_string_member(object_data, "rom");
    if (node_data) {
        gtk_label_set_label(info_page->label_rom_info, node_data);
    } else {
        gtk_label_set_label(info_page->label_rom_info, str_unknown);
    }
    node_data = NULL;


}


void gnd_device_info_module_ui_set_info_not_connected(GndDeviceInfoModule *self)
{
    gchar * str_unknown = "未知";
    GndDeviceInfoPage * info_page = gnd_app_get_mainwin(self->app)->device_info_page;

    gtk_label_set_label(info_page->label_model_info, str_unknown);
    gtk_label_set_label(info_page->label_manuf_info, str_unknown);
    gtk_label_set_label(info_page->label_sysver_info, str_unknown);
    gtk_label_set_label(info_page->label_kernel_info, str_unknown);
    gtk_label_set_label(info_page->label_imei_info, str_unknown);
    gtk_label_set_label(info_page->label_mac_info, str_unknown);
    gtk_label_set_label(info_page->label_cpu_info, str_unknown);
    gtk_label_set_label(info_page->label_sdk_api_info, str_unknown);
    gtk_label_set_label(info_page->label_brand_info, str_unknown);
    gtk_label_set_label(info_page->label_product_info, str_unknown);
    gtk_label_set_label(info_page->label_cpu_abi_info, str_unknown);
    gtk_label_set_label(info_page->label_resolution_info, str_unknown);
    gtk_label_set_label(info_page->label_ram_info, str_unknown);
    gtk_label_set_label(info_page->label_rom_info, str_unknown);
}
